package com.huangxunyi.GUET;

/**
 * //=======================================================
 * //		          .----.
 * //		       _.'__    `.
 * //		   .--(^)(^^)---/!\
 * //		 .' @          /!!!\
 * //		 :         ,    !!!!
 * //		  `-..__.-' _.-\!!!/
 * //		        `;_:    `"'
 * //		      .'"""""`.
 * //		     /,  ya ,\\
 * //		    //狗神保佑\\
 * //		    `-._______.-'
 * //		    ___`. | .'___
 * //		   (______|______)
 * //=======================================================
 * Created by huang on 2017/2/25.
 */
public class ContralCmd {
    private final static byte CONTROL_CMD_LOGIN_USERID = 0x1f;
    private final static byte CONTROL_CMD_LOGIN_USERID_REPLY = 0x20;
    private final static byte CONTROL_CMD_LOGIN_PASSWORD = 0x21;
    private final static byte CONTROL_CMD_LOGIN_PASSWORD_REPLY = 0x22;
    private final static byte CONTROL_CMD_LOGOUT_USERID = 0x14;
    private final static byte CONTROL_CMD_LOGOUT_USERID_REPLY = 0x15;
    private final static byte CONTROL_CMD_LOGOUT_PASSWORD = 0x16;
    private final static byte CONTROL_CMD_LOGOUT_PASSWORD_REPLY = 0x17;

    private final static int CONTROL_PACKET_LENGTH = 300;
    private final static int CONTROL_PACKET_FILL_BYTE = 0xff;
    private final static int CONTROL_PACKET_RANDOM_STRING_LENGTH = 0x13;

    private final static String HOST_MAC_ADDR = "08-9e-01-6b-f8-1b";

    private String userName = "1300310332";
    private String password = "123456";
    private int key = 0;
    private int enKey = 0;

    public ContralCmd(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public int getKey() {
        return key;
    }

    private byte[] packCmdPacket(CMDPacketModel model) {
        byte[] re = new byte[CONTROL_PACKET_LENGTH];
        int index = 0;
        try {
            for (byte b : IPClientUtils.short2byte(model.getBanner())) {
                re[index++] = b;
            }
            re[index++] = model.getCommand();
            for (byte b : IPClientUtils.int2byte(model.getResult())) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getUnused1())) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getLen1())) {
                re[index++] = b;
            }
            for (byte b : model.getStr1().getBytes("gbk")) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getLen2())) {
                re[index++] = b;
            }
            for (byte b : model.getStr2().getBytes("gbk")) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getLen3())) {
                re[index++] = b;
            }
            for (byte b : model.getStr3().getBytes("gbk")) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getKey())) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getUnused2())) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getResv())) {
                re[index++] = b;
            }
            for (byte b : IPClientUtils.int2byte(model.getLen4())) {
                re[index++] = b;
            }
            for (byte b : model.getStr4().getBytes("gbk")) {
                re[index++] = b;
            }
            for (int i = index; i < re.length; i++) {
                re[i] = (byte) CONTROL_PACKET_FILL_BYTE;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return re;

    }

    private CMDPacketModel unpackCmdPacket(byte[] packet) {
        CMDPacketModel model = null;
        try {
            if (packet != null && ((int) packet[0] & 0xff) == 0x82
                    && ((int) packet[1] & 0xff) == 0x23) {
                model = new CMDPacketModel();

                model.setCommand(packet[2]);
                int index = 3;

                model.setResult(IPClientUtils.byte2int(packet, index));
                index += 8;

                model.setLen1(IPClientUtils.byte2int(packet, index));
                index += 4;
                model.setStr1(new String(packet, index, model.getLen1(), "gbk"));
                index += model.getLen1();

                model.setLen2(IPClientUtils.byte2int(packet, index));
                index += 4;
                model.setStr2(new String(packet, index, model.getLen2(), "gbk"));
                index += model.getLen2();

                model.setLen3(IPClientUtils.byte2int(packet, index));
                index += 4;
                model.setStr3(new String(packet, index, model.getLen3(), "gbk"));
                index += model.getLen3();

                model.setKey(IPClientUtils.byte2int(packet, index));
                index += 12;

                model.setLen4(IPClientUtils.byte2int(packet, index));
                index += 4;
                model.setStr4(new String(packet, index, model.getLen4(), "gbk"));

            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return model;
    }

    private String getLoginEncryptPassword() {
        String enPswd;
        enPswd = key + password;
        enPswd = IPClientUtils.md5String(enPswd);
        enPswd = enPswd.substring(0, 5).toUpperCase() + userName;
        enPswd = IPClientUtils.md5String(enPswd);
        enPswd = enPswd.toUpperCase();
        enPswd = enPswd.substring(0,
                enPswd.length() > 30 ? 30 : enPswd.length());
        return enPswd;
    }

    public byte[] getLoginUseridPacket() {
        return packCmdPacket(new CMDPacketModel(CONTROL_CMD_LOGIN_USERID, //
                0, //
                IPClientUtils.changeStr(userName, -10),//
                IPClientUtils
                        .getRandomString(CONTROL_PACKET_RANDOM_STRING_LENGTH),//
                "a", //
                "b", //
                IPClientUtils.getRandomInt(88888888, 11111111)));

    }

    public boolean checkLoginUseridReply(byte[] packet) {
        CMDPacketModel model = unpackCmdPacket(packet);
        if (model != null
                && model.getCommand() == CONTROL_CMD_LOGIN_USERID_REPLY) {
            key = model.getKey() - 3344;
            return true;
        } else {
            return false;
        }
    }

    public byte[] getLoginPasswordPacket() {
        return packCmdPacket(new CMDPacketModel(CONTROL_CMD_LOGIN_PASSWORD, //
                0, //
                IPClientUtils
                        .getRandomString(CONTROL_PACKET_RANDOM_STRING_LENGTH),//
                getLoginEncryptPassword(),//
                HOST_MAC_ADDR, //
                "b", //
                IPClientUtils.getRandomInt(88888888, 11111111)));

    }

    public CMDPacketModel checkLoginPasswordReply(byte[] packet) {
        CMDPacketModel model = unpackCmdPacket(packet);
        if (model != null
                && model.getCommand() == CONTROL_CMD_LOGIN_PASSWORD_REPLY) {
            return model;
        }
        return null;
    }

    public byte[] getLogoutUseridPacket() {
        return packCmdPacket(new CMDPacketModel(CONTROL_CMD_LOGOUT_USERID, //
                0, //
                IPClientUtils.changeStr(userName, -15),//
                IPClientUtils
                        .getRandomString(CONTROL_PACKET_RANDOM_STRING_LENGTH),//
                "a", //
                "b", //
                IPClientUtils.getRandomInt(88888888, 11111111)));

    }

    public boolean checkLogoutUseridReply(byte[] packet) {
        CMDPacketModel model = unpackCmdPacket(packet);
        if (model != null
                && model.getCommand() == CONTROL_CMD_LOGOUT_USERID_REPLY) {
            enKey = model.getKey() - 0x2382;
            return true;
        } else {
            return false;
        }
    }

    public byte[] getLogoutPasswordPacket() {
        return packCmdPacket(new CMDPacketModel(CONTROL_CMD_LOGOUT_PASSWORD, //
                0, //
                IPClientUtils
                        .getRandomString(CONTROL_PACKET_RANDOM_STRING_LENGTH),//
                IPClientUtils.flowEncrypt(password, enKey),//
                HOST_MAC_ADDR, //
                "b", //
                (enKey % 1000) * 2 + password.length()));

    }

    public CMDPacketModel checkLogoutPasswordReply(byte[] packet) {
        CMDPacketModel model = unpackCmdPacket(packet);
        if (model != null
                && model.getCommand() == CONTROL_CMD_LOGOUT_PASSWORD_REPLY) {
            return model;
        }
        return null;
    }
}
